package com.dingtalk.yuanhua_spring_project.task;

import com.dingtalk.yuanhua_spring_project.dto.InstanceInfoDTO;
import com.dingtalk.yuanhua_spring_project.pojo.Employee;
import com.dingtalk.yuanhua_spring_project.pojo.Instance;
import com.dingtalk.yuanhua_spring_project.repository.EmployeeRepository;
import com.dingtalk.yuanhua_spring_project.repository.InstanceRepository;
import com.dingtalk.yuanhua_spring_project.service.impl.*;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class HeTongTaskDaily {
    private static final Logger logger = LoggerFactory.getLogger(HeTongTaskDaily.class);
    @Autowired
    private DingTalkYiDaimpl dingTalkYiDaimpl;
    @Autowired
    private DingTalkStorageimpl dingTalkStorageimpl;
    @Autowired
    private DingTalkAccessimpl dingTalkAccessimpl;
    @Autowired
    private DingTalkDingPanimpl dingTalkDingPanimpl;
    @Autowired
    private DingTalkYiDa1_0impl dingTalkYiDa1_0impl;
    @Autowired
    private InstanceRepository instanceRepository;
    @Autowired
    private EmployeeRepository employeeRepository;
    @Value("${app_key}")
    private String app_key;
    @Value("${app_secret}")
    private String app_secret;
    @Value("${app_agentid}")
    private String app_agentid;
    @Value("${app_id}")
    private String app_id;
    @Value("${union_id}")
    private String union_id;
    @Value("${app_type}")
    private String app_type;
    @Value("${system_token}")
    private String system_token;
    @Value("${user_id}")
    private String user_id;
    @Value("${space_id}")
    private String space_id;
    @Value("${hetong_folder_name}")
    private String hetong_folder_name;
    @Value("${hetong_leixing}")
    private String hetong_leixing;
    @Value("${hetong_form_id}")
    private String hetong_form_id;
    @Value("${hetong_xingzhi}")
    private String hetong_xingzhi;
    @Value("${hetong_name}")
    private String hetong_name;
    @Value("${hetong_xiangmu_name}")
    private String hetong_xiangmu_name;
    @Value("${hetong_fileattach}")
    private String hetong_fileattach;
    @Value("${hetong_tuichu_folder_name}")
    private String hetong_tuichu_folder_name;
    @Value("${hetong_jijin_name}")
    private String hetong_jijin_name;

    @Scheduled(cron = "0 30 23 * * ?") // 早上8点和晚上10点执行
    public void executeDailyTask() {
        try {
            logger.info("开始执行 合约-自动化任务");
            String accessToken = dingTalkAccessimpl.getAccessToken();
            Map<String, Map<String, String>> folderList = dingTalkStorageimpl.getFolderList(accessToken, space_id);
            System.out.println(accessToken);

            List<Map<String, String>> formConfigs = new ArrayList<>();
            formConfigs.add(Map.of(
                    "formId", hetong_form_id,
                    "folderName", hetong_folder_name,
                    "jijinNameKey", hetong_jijin_name,
                    "hetongXingZhi", hetong_xingzhi,
                    "hetongMingCheng", hetong_name,
                    "xiangmuNameKey", hetong_xiangmu_name,
                    "fileAttachKey", hetong_fileattach
            ));

            for (Map<String, String> formConfig : formConfigs) {
                logger.info("开始处理表单：{}", formConfig.get("folderName"));
                processForm(accessToken, formConfig.get("formId"), formConfig.get("jijinNameKey"), formConfig.get("xiangmuNameKey"), formConfig.get("jianchengNameKey"), formConfig.get("folderName"), formConfig.get("zibiao"), formConfig.get("fileAttachKey"), folderList);
            }

            List<Employee> employeesWithNoPermission = employeeRepository.findEmployeesWithNoPermission();
            grantPermissions(accessToken, employeesWithNoPermission, folderList);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void processForm(String accessToken, String formId, String jijinNameKey, String xiangmuNameKey, String jianchengNameKey, String folderName, String zibiao, String fileAttachKey, Map<String, Map<String, String>> folderList) {
        try {
            List<String> instanceIdList = dingTalkYiDaimpl.getInstanceIdList(accessToken, this.app_type, formId, this.user_id, this.system_token);
            List<InstanceInfoDTO> existingInstance = instanceRepository.findAllInstanceInfo();

            for (String instanceId : instanceIdList) {
                try {
                    if (existingInstance.stream().anyMatch(existing -> existing.getInstanceId().equals(instanceId))) {
                        continue;
                    }

                    Map<String, ?> instance = dingTalkYiDaimpl.getInstance(accessToken, instanceId);
                    if (instance == null){
                        continue;
                    }
                    String HeTongLeiXing = (String) instance.get(hetong_leixing);
                    String modifiedTimeGMT = (String) instance.get("modifiedTime");
                    String HeTongXingZhi = (String) instance.get(hetong_xingzhi);
                    String HeTongMingCheng = (String) instance.get(hetong_name);
                    String modifiedTime = modifiedTimeGMT.substring(0, 10);

                    List<String> jsonStrings = new ArrayList<>();
                    String[] fileAttachKeys = fileAttachKey.split(",");

                    for (String key : fileAttachKeys) {
                        if (zibiao != null) {
                            List<Map<String, Object>> zibiaoList = (List<Map<String, Object>>) instance.get(zibiao);
                            for (Map<String, Object> value : zibiaoList) {
                                if (value.get(key) != null) {
                                    jsonStrings.add(value.get(key).toString());
                                }
                            }
                        }
                        String jsonString = (String) instance.get(key.trim());
                        if (jsonString != null && !jsonString.isEmpty()) {
                            jsonStrings.add(jsonString);
                        }
                    }

                    if (jsonStrings.isEmpty()) {
                        continue;
                    }

                    String projectName;
                    String jiancheng_name;
                    String folderName2 = null;
                    String FileSaveFolderId;

                    if (Objects.equals(HeTongLeiXing, "退出合同签署")) {
                        String jijin_name = (String) instance.get(jijinNameKey);
                        logger.info("基金文件夹名称:{}",  jijin_name);
                        projectName = (String) instance.get(xiangmuNameKey);
                        logger.info("项目文件夹名称:{}",  jijin_name);
                        jiancheng_name = projectName;
                        Optional<InstanceInfoDTO> existing = existingInstance.stream()
                                .filter(existingInstanceDTO -> existingInstanceDTO.getJijinName().equals(jijin_name) && existingInstanceDTO.getProjectName().equals(projectName))
                                .findFirst();
                        if (existing.isPresent()) {
                            jiancheng_name = existing.get().getJianchengName();
                        }
                        folderName = jiancheng_name + "-退出合同";
                        logger.info("简称文件夹名称:{}",  folderName);
                        FileSaveFolderId = createFolderHierarchy(accessToken, folderList, jijin_name, projectName, folderName);
                        uploadFiles(accessToken, jsonStrings, FileSaveFolderId, modifiedTime);

                        createData(instanceId, jijin_name, jiancheng_name, projectName, folderName, folderName2, modifiedTime);

                        List<ArrayList<?>> employeeList = instance.entrySet().stream()
                                .filter(entry -> entry.getKey().startsWith("employeeField") && entry.getKey().endsWith("id"))
                                .map(Map.Entry::getValue)
                                .filter(value -> value instanceof ArrayList)
                                .map(value -> (ArrayList<?>) value)
                                .collect(Collectors.toList());

                        List<Object> new_employeeList = employeeList.stream()
                                .flatMap(ArrayList::stream)
                                .collect(Collectors.toList());

                        new_employeeList = new_employeeList.stream()
                                .distinct()
                                .collect(Collectors.toList());
                        System.out.println(new_employeeList);

                        for (Object employee : new_employeeList) {
                            createEmployee(jijin_name, projectName, jiancheng_name, employee.toString());
                        }
                    } else if (Objects.equals(HeTongLeiXing, "合同")) {
                        projectName = (String) instance.get(xiangmuNameKey);
                        jiancheng_name = projectName;

                        // 去重处理，根据 jijinName 去重
                        Map<String, List<InstanceInfoDTO>> existingGroupedByJijinName = existingInstance.stream()
                                .filter(existingInstanceDTO -> existingInstanceDTO.getProjectName().equals(projectName))
                                .collect(Collectors.groupingBy(InstanceInfoDTO::getJijinName));

                        for (Map.Entry<String, List<InstanceInfoDTO>> entry : existingGroupedByJijinName.entrySet()) {
                            String jijin_name = entry.getKey();
                            List<InstanceInfoDTO> existingList = entry.getValue();

                            // 获取第一个匹配的 jianchengName
                            String firstJianchengName = existingList.get(0).getJianchengName();

                            folderName = firstJianchengName + "-流程文件";
                            folderName2 = HeTongXingZhi + "-" + HeTongMingCheng;
                            FileSaveFolderId = createFolderHierarchy(accessToken, folderList, jijin_name, projectName, folderName, folderName2);
                            uploadFiles(accessToken, jsonStrings, FileSaveFolderId, modifiedTime);

                            createData(instanceId, jijin_name, firstJianchengName, projectName, folderName, folderName2, modifiedTime);

                            List<ArrayList<?>> employeeList = instance.entrySet().stream()
                                    .filter(e -> e.getKey().startsWith("employeeField") && e.getKey().endsWith("id"))
                                    .map(Map.Entry::getValue)
                                    .filter(value -> value instanceof ArrayList)
                                    .map(value -> (ArrayList<?>) value)
                                    .collect(Collectors.toList());

                            List<Object> new_employeeList = employeeList.stream()
                                    .flatMap(ArrayList::stream)
                                    .collect(Collectors.toList());

                            new_employeeList = new_employeeList.stream()
                                    .distinct()
                                    .collect(Collectors.toList());
                            System.out.println(new_employeeList);

                            for (Object employee : new_employeeList) {
                                createEmployee(jijin_name, projectName, firstJianchengName, employee.toString());
                            }
                        }
                    } else {
                        continue;
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String createFolderHierarchy(String accessToken, Map<String, Map<String, String>> folderList, String jijin_name, String projectName, String... folderNames) {
        try {
            if (!folderList.containsKey("/" + jijin_name)) {
                dingTalkStorageimpl.addFolder(jijin_name, space_id, "0", accessToken);
                folderList = dingTalkStorageimpl.getFolderList(accessToken, space_id);
            }
            String jijinFolderId = folderList.get("/" + jijin_name).get("id");

            if (!folderList.containsKey("/" + jijin_name + "/" + projectName)) {
                dingTalkStorageimpl.addFolder(projectName, space_id, jijinFolderId, accessToken);
                folderList = dingTalkStorageimpl.getFolderList(accessToken, space_id);
            }
            String xiangmuFolderId = folderList.get("/" + jijin_name + "/" + projectName).get("id");

            String currentFolderId = xiangmuFolderId;
            String path = "/" + jijin_name + "/" + projectName;
            for (String folderName : folderNames) {
                path += "/" + folderName;
                if (!folderList.containsKey(path)) {
                    dingTalkStorageimpl.addFolder(folderName, space_id, currentFolderId, accessToken);
                    folderList = dingTalkStorageimpl.getFolderList(accessToken, space_id);
                }
                currentFolderId = folderList.get(path).get("id");
            }
            logger.info("文件夹路径:{}", path);
            return folderList.get(path).get("uuid");
        } catch (Exception e) {
            logger.error("创建文件夹失败:{}", e.getMessage());
            return null;
        }
    }

    private void uploadFiles(String accessToken, List<String> jsonStrings, String FileSaveFolderId, String modifiedTime) {
        ObjectMapper objectMapper = new ObjectMapper();
        for (String jsonString : jsonStrings) {
            try {
                List<Map<String, Object>> fileList = objectMapper.readValue(jsonString, new TypeReference<List<Map<String, Object>>>() {});

                List<String> downloadUrls = fileList.stream()
                        .map(file -> (String) file.get("downloadUrl"))
                        .collect(Collectors.toList());

                List<String> downloadFileNames = fileList.stream()
                        .map(file -> (String) file.get("name"))
                        .collect(Collectors.toList());

                for (int i = 0; i < downloadUrls.size(); i++) {
                    try {
                        String fileSavePath = dingTalkYiDa1_0impl.getDownloadUrl(accessToken, downloadUrls.get(i), this.system_token, this.user_id, this.app_type, downloadFileNames.get(i));
                        String originalFileName = downloadFileNames.get(i);
                        String fileNameWithTime = insertTimeBeforeExtension(originalFileName, modifiedTime);
                        dingTalkStorageimpl.GetFileUploadInfoByDentryId(accessToken, FileSaveFolderId, fileSavePath, fileNameWithTime);
                    } catch (Exception e) {
                        logger.error("下载和上传文件失败", e);
                    }
                }
            } catch (IOException e) {
                logger.error("JSON解析失败", e);
            }
        }
    }

    private String insertTimeBeforeExtension(String fileName, String modifiedTime) {
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex == -1) {
            // 如果没有找到扩展名，直接在文件名末尾添加 _time
            return fileName + "_" + modifiedTime;
        }
        String namePart = fileName.substring(0, lastDotIndex);
        String extensionPart = fileName.substring(lastDotIndex);
        return namePart + "_" + modifiedTime + extensionPart;
    }

    private void createData(String instanceId, String jijin_name, String jiancheng_name, String projectName, String folderName, String folderName2, String modifiedTime) {
        if (!instanceRepository.existsByInstanceIdAndModifiedTime(instanceId, modifiedTime)) {
            Instance instanceEntity = new Instance();
            instanceEntity.setInstanceId(instanceId);
            instanceEntity.setJijinName(jijin_name);
            instanceEntity.setJianchengName(jiancheng_name);
            if (folderName2 != null && !folderName2.isEmpty()) {
                instanceEntity.setFolderList("/" + jijin_name + "/" + jiancheng_name + "/" + folderName + "/" + folderName2);
            } else {
                instanceEntity.setFolderList("/" + jijin_name + "/" + jiancheng_name + "/" + folderName);
            }
            instanceEntity.setInvested(true);
            instanceEntity.setModifiedTime(modifiedTime);
            instanceEntity.setProjectName(projectName);
            instanceRepository.save(instanceEntity);
        }
    }

    private void createEmployee(String jijin_name, String projectName, String jiancheng_name, String employeeId) {
        if (!employeeRepository.existsByJijinNameAndProjectNameAndEmployeeId(jijin_name, projectName, employeeId)) {
            Employee employeeEntity = new Employee();
            employeeEntity.setJijinName(jijin_name);
            employeeEntity.setProjectName(projectName);
            employeeEntity.setJianchengName(jiancheng_name);
            employeeEntity.setEmployeeId(employeeId);
            employeeEntity.setHasPermission(false);
            employeeRepository.save(employeeEntity);
        }
    }

    private void grantPermissions(String accessToken, List<Employee> employeesWithNoPermission, Map<String, Map<String, String>> folderList) throws Exception {
        for (Employee employee : employeesWithNoPermission) {
            String jijin_name = employee.getJijinName();
            String xiangmu_name = employee.getProjectName();
            String folderPath = "/" + jijin_name + "/" + xiangmu_name;

            if (folderList.containsKey(folderPath)) {
                String uuid = folderList.get(folderPath).get("uuid");
                dingTalkStorageimpl.addPermission(accessToken, employee.getEmployeeId(), uuid);
                employee.setHasPermission(true);
                employeeRepository.save(employee);
            } else {
                logger.info("Folder path " + folderPath + " not found in folderList");
            }
        }
    }

    private boolean isInstanceMatched(List<InstanceInfoDTO> existingInstances, String jijinName, String jianchengName, String projectName) {
        for (InstanceInfoDTO existingInstance : existingInstances) {
            if (existingInstance.getJijinName().equals(jijinName) &&
                    existingInstance.getJianchengName().equals(jianchengName) &&
                    existingInstance.getProjectName().equals(projectName)) {
                return true;
            }
        }
        return false;
    }

}
